//
//  JuSwift5.swift
//  JuSwift
//
//  Created by Juvid on 2020/9/24.
//  Copyright © 2020 Juvid. All rights reserved.
//

import UIKit



class JuSwift5: NSObject {
    override init() {
        super.init()
        testStr()
        interpolation()
        testDynamic()
    }
    func  testStr(){
        //before
        let rain = "The \"rain\" in \"Spain\" falls mainly on the Spaniards."
        //after
        let rain2 = #"The "rain" in "Spain" falls mainly on the Spaniards."#
        print(rain)
        print(rain2)

        let answer = 42
        // before
        let dontpanic = "The answer to life, the universe, and everything is \(answer)"
        // after
        let dontpanic2 = #"The answer to life, the universe, and everything is \#(answer)"#
        print(dontpanic)
        print(dontpanic2)

        let str = ###"My dog said "woof"##gooddog"###
        print(str)

        let multiline = #"""
        The answer to life,
        the universe,
        and everything is \#(answer).
        """#
        print(multiline)

//正则表达式
//        // before
//        let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+"
//        // after
//        let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#
    }
//    func handleError(){
//
//    }
//    func handleResponse(){
//
//    }
//    func testResult (){
//
//        URLSession.shared.dataTask(with: URL.init(string: "www")!) {(data, response, error) in
//            guard error != nil else { self.handleError() }
//            guard let data = data, let response = response else { return // Impossible? }
//
//            self.handleResponse()
//            }
//        }
//
//    }

    func interpolation() {
        let number = 123.666
        print("Hello ,numberis \(number)")
        print("Hello, number is \(number, format:"%.2f")")
        print("Hello, number is \(nil, format:"%.2f")")
        print("Hello, number is \(number,desc:"test")")
    }
    func testDynamic(){
        // 调用方式
        let random = RandomNumberGenerator()
        let num = random(2) // random(2)等同于random.dynamicallyCall(withArguments: [2])
        showOld(error: PasswordError.obvious)
        showNew(error: PasswordError.simple)
        print(baz())
    }

}
//SE-0228
extension String.StringInterpolation {
//方法相同，参数不同
    public mutating func appendInterpolation(_ number: Double?, format formatString: String) {
        if let number = number{
            return appendLiteral(String(format: formatString, number))
        } else {
            return appendLiteral("nil")
        }
    }
    public mutating func appendInterpolation(_ number: Double?,desc : String) {
        if let number = number{
            return appendLiteral(String("\(number)\(desc)"))
        } else {
            return appendLiteral("nil")
        }
    }
}

// 如果需要添加@dynamicCallable属性, 就必须要实现以下方法中的一个或者两个:
// 不需要指定参数名
// func dynamicallyCall(withArguments args: [Int]) -> Double
// 指定参数名的方法
// func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double
// 定义方式
//SE-0216
@dynamicCallable
struct RandomNumberGenerator {
    func dynamicallyCall(withArguments args: [Int]) -> Double {
        let numberOfZeroes = Double(args.first ?? 0)
        let maximum = pow(10, numberOfZeroes)
        return Double.random(in: 0...maximum)
    }
    func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double{
        return 3.0
    }
}


//SE-0192
enum PasswordError: Error {
    case short
    case obvious
    case simple
}

func showOld(error: PasswordError){
    switch error {
        case .short:
        print("Your password was too short.")
        case .obvious:
        print("Your password was too obvious.")
        default:
        print("Your password was too simple.")
    }
}

func showNew(error: PasswordError) {
    switch error {
    case .short:
        print("Your password was too short.")
    case .obvious:
        print("Your password was too obvious.")

    @unknown default:
        print("Your password wasn't suitable.")
    }
}

//enum X {
//    case foo(bar: Int...)
//}
//func baz() -> X {
//    return .foo(bar: 0, 1, 2, 3)
//}

enum X {
    case foo(bar: [Int])
}

func baz() -> X {
    return .foo(bar: [0, 1, 2, 3])
}

